package com.sunlord.utils;

import OThinker.Common.Organization.Models.Unit;
import OThinker.Common.Organization.enums.UnitType;
import OThinker.H3.Entity.Settings.BizDbConnectionConfig;
import com.h3bpm.base.util.AppUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 获取其他数据库连接参数
 * @author AUTH zhengyj
 * 2018-09-30
 */
public class NewDbConfigUtil {
    public  static  final String CLASSNAME_SQL_SERVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    public  static  final String CLASSNAME_MYSQL = "com.mysql.jdbc.Driver";
    public  static  final String CLASSNAME_ORACLE = "oracle.jdbc.OracleDriver";
    /**
     * 信捷 erp sql server
     */
    public static  final  String DBCODE_XINJIE_SQLSERVER = "D1_2012XJ";
    //
    public static  final  String DBCODE_SUNLORD_ENGINE_ORACLE = "Engine";

    private static final Logger LOGGER = LoggerFactory.getLogger(DbConfigUtil.class);


    public static BizDbConnectionConfig DBConfig = null;

    public static List<Unit> unitList = null;

    public static BizDbConnectionConfig getDBConfigByCode(String code) {

        try {
            DBConfig = AppUtility.getEngine().getSettingManager().GetBizDbConnectionConfig(code);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return DBConfig;
    }

    public static List<Unit> getAllUnit(UnitType unitType){
        try {
            unitList =  AppUtility.getEngine().getOrganization().GetAllUnits(unitType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return unitList;
    }


    /**
     * 获取连接
     * @param className
     * @param dbCode
     * @return
     */
    public static Connection getConn(String className,String dbCode)
    {
        Connection connection = null;
        try {
            Class.forName(className);
        } catch (ClassNotFoundException e) {

        }
        getDBConfigByCode(dbCode);
        try {
             connection = DriverManager.getConnection(DBConfig.getDbConnectionString(), DBConfig.getUserName(), DBConfig.getPassword());
        } catch (SQLException e) {

        }
        return connection;
    }

    /**
     * 关闭连接
     * @param conn
     */
    public static void closeConn(Connection conn) {
        if (null != conn) {
            try {
                conn.close();
            } catch (SQLException e) {
                System.out.println("关闭连接失败！");
                //e.printStackTrace();
            }
        }
    }


    /**
     *
     * @param className
     * @param dbCode
     * @param sql
     * @return
     */
    public static List<Map<String,Object>> executeQuerySql(String className, String dbCode, String sql){

        Connection conn = null;
        PreparedStatement  pstmt = null;
        ResultSet rs = null;
        try {        
            conn = DbConfigUtil.getConn(className, dbCode);
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();

            return convertList(rs);

        }catch (Exception e) {
            e.printStackTrace();
            LOGGER.warn(e.getMessage());
            try {
                conn.rollback();
            } catch (SQLException sqle) {
                LOGGER.warn(sqle.getMessage());
            }
        }finally {
            try {
                if (rs != null){
                    rs.close();
                }
                if (pstmt != null){
                    pstmt.close();
                }
                DbConfigUtil.closeConn(conn);
            }catch (Exception e){
                e.printStackTrace();

            }
        }

        
        return null;
    }

    private static List<Map<String,Object>> convertList(ResultSet rs) throws SQLException {
        List<Map<String,Object>> list = new ArrayList<>();
        ResultSetMetaData md = rs.getMetaData();
        int columnCount = md.getColumnCount();
        Map<String,Object> rowData;
        while (rs.next()) {
            rowData = new HashMap<>(16);
            for (int i = 1; i <= columnCount; i++) {
                rowData.put(md.getColumnName(i), rs.getObject(i));
            }
            list.add(rowData);
        }
        return list;
    }

    public static boolean executeUpdateSql( String className,String dbCode,Object sql){
        boolean flag = false;
        Connection conn = null;
        Statement stmt = null;

        try {

            conn = DbConfigUtil.getConn(className, dbCode);
            conn.setAutoCommit(false);
            stmt = conn.createStatement();
            executeUpdate(sql, stmt);
            conn.commit();

            flag = true;

        }catch (Exception e) {
            e.printStackTrace();
            LOGGER.warn(e.getMessage());
            try {
                conn.rollback();
            } catch (SQLException sqle) {
                LOGGER.warn(sqle.getMessage());
            }
        }finally {
            try {
                if (stmt != null){
                    stmt.close();
                }
                DbConfigUtil.closeConn(conn);
            }catch (Exception e){
                e.printStackTrace();

            }
        }

        return flag;
    }

    private static void executeUpdate(Object sql, Statement stmt) throws SQLException {
        if (sql instanceof  List) {
            if (((List)sql).get(0) instanceof String){
                List<String> sqlList = (List<String>)sql;
                for (int i = 0; i < sqlList.size(); i++) {
                    stmt.executeUpdate(sqlList.get(i));
                }
            }
        }else if(sql instanceof  String){
            stmt.executeUpdate((String) sql);
        }
    }


}

